Skip to content

fix(export): match harness allowedTools for customer tools and keep model parameters - #2456

Merged
aidandaly24 merged 1 commit into
aws:refactorfrom
amhegazy-mp4:fix/export-harness-fidelity
Sep 30, 2026
Merged

aidandaly24 merged 1 commit into
aws:refactorfrom
amhegazy-mp4:fix/export-harness-fidelity

Conversation

@amhegazy-mp4

@amhegazy-mp4 amhegazy-mp4 commented Sep 29, 2026 •

Copy link
Copy Markdown

Description

agentcore export harness now matches the harness it exports in two places:

  • allowedTools for configured tools. A bare pattern (shell, file_*) selects built-in tools only, and @name selects a configured tool (MCP server, inline function, gateway, browser, code interpreter), as the harness does. Previously @name dropped the tool and a bare name kept it. A bare built-in name such as shell now also selects the built-in, which previously required @builtin/shell. matchesAllowedTools now takes the server and tool separately instead of a flattened name.
  • @server/tool for MCP servers. A pattern that names specific tools (@exa/search, @exa/web_*) now narrows the MCP server to those tools through MCPClient(tool_filters=...), matched on the server's own tool name or <server>_<tool>. Previously the whole server was kept, exposing all of its tools. @exa and * still load every tool.
  • Model additionalParams. For bedrock, open_ai, and gemini, export harness --arn carries the harness model's additionalParams into the generated model/load.py (Bedrock additional_args; params for Mantle, OpenAI, and Gemini) instead of dropping them with an export note. Explicit model settings (temperature, max tokens, ...) take precedence. The local harness spec still omits the field, since harness.yaml accepts it only for lite_llm, so the values are passed to the export alongside the spec.

Behavior changes for new exports: a bare configured-tool name in allowedTools no longer keeps that tool (use @name), matching the harness.

Related Issue

Closes #2455

Documentation PR

Not applicable.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

  • I ran bun test
  • I ran the relevant end-to-end tests with bun run test:e2e, or explained why they are not applicable: there are no export end-to-end tests. Instead I rendered an export and ran it against Bedrock: allowedTools: ["@mcp"] kept the MCP server and the model called its tool; @mcp/order_* loaded only the matching tool, and Bedrock accepted the carried-over additionalParams.
  • I ran bun run typecheck
  • I ran bun run lint:check
  • I ran bun run format:check
  • I ran bun run build
  • If I modified src/assets/, I updated affected snapshots with bun test <test-file> --update-snapshots and committed them (no snapshots changed)

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.

@github-actions github-actions Bot added the size/m PR size: M label Sep 29, 2026
@amhegazy-mp4
amhegazy-mp4 force-pushed the fix/export-harness-fidelity branch from 247d056 to 86eca92 Compare September 29, 2026 19:57
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 29, 2026
@amhegazy-mp4 amhegazy-mp4 changed the title fix(export): match harness allowedTools for configured tools and keep model additionalParams fix(export): match harness allowedTools for customer tools and keep model parameters Sep 29, 2026
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 29, 2026
@amhegazy-mp4
amhegazy-mp4 force-pushed the fix/export-harness-fidelity branch from 86eca92 to 667fe6c Compare September 29, 2026 20:25
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 29, 2026
@codecov-commenter

codecov-commenter commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.36%. Comparing base (a7dc25c) to head (e697e61).
⚠️ Report is 3 commits behind head on refactor.

Additional details and impacted files
@@            Coverage Diff            @@
##           refactor    #2456   +/-   ##
=========================================
  Coverage     97.35%   97.36%           
=========================================
  Files           632      632           
  Lines         46268    46296   +28     
=========================================
+ Hits          45044    45075   +31     
+ Misses         1224     1221    -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

aidandaly24
aidandaly24 previously approved these changes Sep 30, 2026
const allowed =
tool.type === "inline_function"
? matchesAllowedTools(tool.name, tool.name, allowedPatterns)
: isServerAllowed(tool.name, allowedPatterns);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is tool filter being preserved here?

for eg: @exa/search should expose only /search, but the export keeps the whole Exa server without the filter, exposing all its tools. Could we pass the tool pattern to MCPClient.tool_filters?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks. @server/tool now narrows the MCP server through MCPClient(tool_filters=...), matching the server's own tool name or <server>_<tool> (the harness accepts both). @exa and * still load every tool. Checked against a live MCP server: @local/order_* loads only order_status.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for testing!

@amhegazy-mp4
amhegazy-mp4 force-pushed the fix/export-harness-fidelity branch from e69b854 to 98aac5e Compare September 30, 2026 17:03
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 30, 2026
@amhegazy-mp4
amhegazy-mp4 force-pushed the fix/export-harness-fidelity branch from 98aac5e to f82402a Compare September 30, 2026 17:47
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 30, 2026
aidandaly24
aidandaly24 previously approved these changes Sep 30, 2026
modelId: model.modelId,
modelApiFormat: model.apiFormat,
// Provider parameters; the explicit model settings below take precedence over them.
modelAdditionalParams:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had my agent test this e2e and seems like preserving guardrailConfig causes exported runtimes to call Bedrock guardrails, but the generated role lacks bedrock:ApplyGuardrail, so invocation fails with AccessDenied. can we please generate that policy?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. When bedrockModelConfig.additionalParams sets a guardrailConfig, the export now adds a bedrock:ApplyGuardrail policy (bedrock-guardrail-policy.json) to the runtime role, scoped to the guardrail ARN, or to guardrail/<id> when only an ID is given.

top_p={{modelTopP}},
{{/if}}
{{#if modelAdditionalParams}}
additional_args=json.loads({{pyJsonStr modelAdditionalParams}}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we ensure the explicit model settings take priority? Strands applies additional_args after max_tokens, temperature, and top_p; an inferenceConfig inside additionalParams therefore overrides those explicit settings.

for eg, additionalParams.inferenceConfig.maxTokens currently overrides max_tokens, even though the code intends the explicit value to win.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that additional_args wins on Bedrock Converse. The harness behaves the same way: it builds BedrockModel with the explicit settings plus additional_args, and Strands applies those last. So the export matches the harness here, and changing the precedence only in the export would make the two diverge. The comment claiming explicit settings win was wrong; it now says what the harness docs say: provider-specific parameters are passed through to the model provider unchanged. On OpenAI, Gemini, LiteLLM, and Mantle the explicit settings still take precedence, in both the harness and the export.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I see, makes sense to me!

…odel parameters

- allowedTools: a bare pattern selects builtins only, and @server selects
  a customer tool (MCP server, inline function, gateway, browser, code
  interpreter), as the harness runtime does. Previously @server dropped
  the tool and a bare name kept it; a bare builtin name ("shell") now
  also selects the builtin, as intended.
- @server/tool narrows an MCP server to the matching tools through MCP
  tool filters, matched on the server's own tool name or <server>_<tool>,
  as the harness does.
- Service model additionalParams for bedrock, open_ai, and gemini are
  carried into the generated model loader instead of being dropped with
  a note. A Bedrock guardrailConfig in them adds a bedrock:ApplyGuardrail
  policy to the runtime role. The local harness spec still omits them,
  since its deploy schema accepts them only for lite_llm.
@github-actions github-actions Bot added the size/m PR size: M label Sep 30, 2026
@aidandaly24
aidandaly24 merged commit 1fd3ac0 into aws:refactor Sep 30, 2026
12 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants